package org.gfix.binding;

import static org.junit.Assert.*;

import java.util.ArrayList;
import java.util.List;

import org.gfix.annotation.FixBinding;
import org.gfix.annotation.FixBindingSet;
import org.gfix.annotation.FixFormatter;
import org.gfix.annotation.FixMessageBinding;
import org.gfix.annotation.FixMessageBindingSet;
import org.gfix.converter.EnumConverter;
import org.gfix.types.FixVersion;
import org.junit.Test;

public class TypeSelectorTest {

	@Test
	public void testNewTag() throws FixBindingException {
		List<ClassFixBindingDescription> desc = new ArrayList<ClassFixBindingDescription>();
		desc.add(new ClassFixBindingDescription(FixMessage1.class));
		desc.add(new ClassFixBindingDescription(FixMessage2.class));
		desc.add(new ClassFixBindingDescription(FixMessage3.class));
		
		TypeSelector ts = new TypeSelector();
		ts.reset(desc);
		String fixVersion = EnumConverter.getEnumConverter(FixVersion.class).convertToFix(FixVersion.FIX_41);
		ArrayList al = new ArrayList();
		
		assertNull(ts.newTag(8, fixVersion,al));
		ClassFixBindingDescription fdm = ts.newTag(35, "D", al);
		assertNotNull(fdm);
		assertEquals(ts.getSelectedVersion(), FixVersion.FIX_41);
		assertEquals(fdm.getBoundType(), FixMessage1.class);
	}
	
	@Test
	public void testMultiBoundNotSpecified() throws FixBindingException {
		List<ClassFixBindingDescription> desc = new ArrayList<ClassFixBindingDescription>();
		desc.add(new ClassFixBindingDescription(FixMessage2.class));
		desc.add(new ClassFixBindingDescription(FixMessage2A.class));
		
		TypeSelector ts = new TypeSelector();
		ts.reset(desc);
		String fixVersion = EnumConverter.getEnumConverter(FixVersion.class).convertToFix(FixVersion.FIX_41);
		ArrayList al = new ArrayList();
		
		assertNull(ts.newTag(8, fixVersion,al));
		ClassFixBindingDescription fdm = ts.newTag(35, "8", al);
		assertNull(fdm);
		fdm = ts.newTag(20, "G", al);
		assertNotNull(fdm);
		assertEquals(ts.getSelectedVersion(), FixVersion.FIX_41);
		assertEquals(fdm.getBoundType(), FixMessage2.class);
	}
	
	@Test
	public void testMultiBoundSpecified() throws FixBindingException {
		List<ClassFixBindingDescription> desc = new ArrayList<ClassFixBindingDescription>();
		desc.add(new ClassFixBindingDescription(FixMessage2.class));
		desc.add(new ClassFixBindingDescription(FixMessage2A.class));
		
		TypeSelector ts = new TypeSelector();
		ts.reset(desc);
		String fixVersion = EnumConverter.getEnumConverter(FixVersion.class).convertToFix(FixVersion.FIX_41);
		ArrayList al = new ArrayList();
		
		assertNull(ts.newTag(8, fixVersion,al));
		ClassFixBindingDescription fdm = ts.newTag(35, "8", al);
		assertNull(fdm);
		fdm = ts.newTag(20, "1", al);
		assertNull(fdm);
		fdm = ts.newTag(10, "100", al);
		assertNotNull(fdm);
		assertEquals(ts.getSelectedVersion(), FixVersion.FIX_41);
		assertEquals(fdm.getBoundType(), FixMessage2A.class);
	}

}

//35=D => NewOrderSingle
@FixMessageBindingSet
(
		fixBindings={@FixMessageBinding(fixTag=35 , fixVersion=FixVersion.FIX_41, matches="D", sending="D")}
)
class FixMessage1
{
	@FixBindingSet(fixBindings=
	{
		@FixBinding(fixVersion=FixVersion.FIX_40, fixTag=61,formatter=@FixFormatter),
		@FixBinding(fixVersion=FixVersion.FIX_41, fixTag=71,formatter=@FixFormatter)
	})
	private boolean booleanType;

	public boolean getBooleanType() {
		return booleanType;
	}

	public void setBooleanType(boolean booleanType) {
		this.booleanType = booleanType;
	}
	
	
}

//35=8 => Execution Report
@FixMessageBindingSet
(
		fixBindings={@FixMessageBinding(fixTag=35 , fixVersion=FixVersion.FIX_41, matches="8", sending="8")}
)
class FixMessage2
{
	@FixBindingSet(fixBindings=
	{
		@FixBinding(fixVersion=FixVersion.FIX_40, fixTag=61,formatter=@FixFormatter),
		@FixBinding(fixVersion=FixVersion.FIX_41, fixTag=71,formatter=@FixFormatter)
	})
	private boolean booleanType;	
}

//35=8 => Execution Report
// 20=1 => Ack
@FixMessageBindingSet
(
		fixBindings={@FixMessageBinding(fixTag=35 , fixVersion=FixVersion.FIX_41, matches="8", sending="8"),
				@FixMessageBinding(fixTag=20 , fixVersion=FixVersion.FIX_41, matches="1", sending="1")}
)
class FixMessage2A
{
	
}

//35=FF =>Some custom message 
@FixMessageBindingSet
(
		fixBindings={@FixMessageBinding(fixTag=35 , fixVersion=FixVersion.FIX_41, matches="FF", sending="FF")}
)
class FixMessage3
{
	
}

//35=FF =>Some custom message 
@FixMessageBindingSet
(
		fixBindings={@FixMessageBinding(fixTag=35 , fixVersion=FixVersion.FIX_41, matches="FAIL", sending="FF")}
)
class FixMessageNoConstructor
{
	public FixMessageNoConstructor(String s)
	{}
}
